package com.bob.shirodemo.base.shiro;

import com.bob.shirodemo.entity.ResourceEntity;
import com.bob.shirodemo.entity.RoleEntity;
import com.bob.shirodemo.entity.UserEntity;
import com.bob.shirodemo.service.UserService;
import lombok.Data;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.util.DigestUtils;
import sun.security.provider.MD5;

import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

@Data
public class UserRealm extends AuthorizingRealm {

    private UserService userService;

    /**
     * 授权
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        String username = (String) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        // 根据用户名查询当前用户拥有的角色
        Set<RoleEntity> roles = userService.getRolesByUsername(username);
        Set<String> roleNames = new HashSet<String>();
        for (RoleEntity role : roles) {
            roleNames.add(role.getName());
        }
        // 将角色名称提供给info
        authorizationInfo.setRoles(roleNames);
        // 根据用户名查询当前用户权限
        Set<String> uris = new HashSet<>();
        roles.forEach(role -> {
           uris.addAll(role.getResources().stream().map(resource -> resource.getUri()).collect(Collectors.toList()));
        });
//        Set<String> permissionNames = new HashSet<String>();
//        for (Permission permission : permissions) {
//            permissionNames.add(permission.getPermission());
//        }
        // 将权限名称提供给info
        authorizationInfo.setStringPermissions(uris);

        return authorizationInfo;
    }

    /**
     * 认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //因为在SecurityInterceptor中使用的是UsernamePasswordToken，所以这里的Principal就是他的用户名称
        String tokenStr = (String) token.getPrincipal();
        UserEntity user = userService.getUserByToken(tokenStr);
        if (user == null) {
            // 用户名不存在抛出异常
            throw new UnknownAccountException();
        }
//        if (user.getLocked() == 0) {
//            // 用户被管理员锁定抛出异常
//            throw new LockedAccountException();
//        }
        //这里的密码可以存加密之后的密码，
        String encodePassword = DigestUtils.md5DigestAsHex((user.getPassword() + "salt").getBytes());
        SimpleHash hash = new SimpleHash("md5", user.getPassword(), "salt", 2);
//        String encodedPassword = hash.toHex();
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(), hash,
                ByteSource.Util.bytes("salt"), getName());
        return authenticationInfo;
    }
}
